/*TCP client program using Berkley Sockets*/

/*Compile command: cc -o tcpc tcpc.c -lnsl -lsocket*/
/*Run Command: ./tcpc localhost */

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<stdlib.h>	// exit function	
#include<string.h>

#define SERVER_PORT 5488
#define MAX_LINE 256
#define DESTINATION "smtp.asu.edu"
#define ASU_SMTP_PT 25


int main (int argc,char * argv[])
{
	FILE *fp;
	struct hostent *hp;
	struct sockaddr_in sin;
	char * helo;
	char * data;
	char * to, * from, * subj;
	char buf[MAX_LINE];
	char emptyBuf[MAX_LINE];
	int s;
	int len=0;

	helo = (char *)malloc(MAX_LINE);
	to = (char *)malloc(MAX_LINE);
	from = (char *)malloc(MAX_LINE);
	data = (char *)malloc(MAX_LINE);
	subj = (char *)malloc(MAX_LINE);

	if (argc>=3)
	{
		// create the to and from commands to pass
		memcpy(from, emptyBuf, strlen(emptyBuf));
		strcat(from, "MAIL FROM: <");
		strcat(from, argv[1]);
		strcat(from, ">\n");

		memcpy(to, emptyBuf, strlen(emptyBuf));
		strcat(to, "RCPT TO: <");
		strcat(to, argv[2]);
		strcat(to, ">\n");

		memcpy(data, emptyBuf, strlen(emptyBuf));
		strcat(data, "DATA\n");

		memcpy(helo, emptyBuf, strlen(emptyBuf));
		strcat(helo, "HELO smtp.asu.edu\n");

		// if there is a subject
		if (argc > 3) {
			memcpy(subj, emptyBuf, strlen(emptyBuf));
			strcat(subj, "Subject: ");
				strcat(subj, argv[3]);
			strcat(subj, "\n\n");
		}
	}
	else
	{
		free(subj);
		free(to);
		free(data);
		free(from);
		fprintf(stderr,"Missing to and from addresses\n");
		exit(1);
	}

	hp = gethostbyname(DESTINATION);
	if (!hp)
	{
		free(subj);
		free(to);
		free(data);
		free(from);
		fprintf(stderr,"simplex-talk:unknown host: %s\n",DESTINATION);
		exit(1);
	}

	bzero((char *)&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	bcopy(hp->h_addr, (char *)&sin.sin_addr,hp->h_length);
	sin.sin_port = htons(ASU_SMTP_PT);

	if ((s = socket(PF_INET, SOCK_STREAM,0)) < 0)
	{
		free(subj);
		free(to);
		free(data);
		free(from);
		perror("simplex_talk: socket error");
		exit(1);
	}

	if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
	{
		free(subj);
		free(to);
		free(data);
		free(from);
		perror("simplex_talk: connect error");
		close(s);
		exit(1);
	}

	// This section will send the hello,
	// to and from, as well as the data.	
	send(s, helo, strlen(helo), 0);
	read(s, buf, 255);
	fputs(buf, stdout);
	memcpy(buf,emptyBuf,MAX_LINE);

	send(s, from, strlen(from), 0);
	read(s, buf, 255);
	fputs(buf, stdout);
	memcpy(buf,emptyBuf,MAX_LINE);

	send(s, to, strlen(to), 0);
	read(s, buf, 255);
	fputs(buf, stdout);
	memcpy(buf,emptyBuf,MAX_LINE);

	send(s, data, strlen(data), 0);
	read(s, buf, 255);
	fputs(buf, stdout);
	memcpy(buf,emptyBuf,MAX_LINE);

	if (argc == 4)
		send(s, subj, strlen(subj), 0);
	
	do
	{
		memcpy(buf, emptyBuf, strlen(emptyBuf));
		fgets(buf, sizeof(buf), stdin);
		buf[MAX_LINE-1] = '\0';
		len = strlen(buf) + 1;
		send(s, buf, strlen(buf), 0);
	} while (strcmp(buf, ".\n"));

	// free the array
	free(subj);
	free(to);
	free(data);
	free(from);
	return 0;
}
